﻿using System.Collections.Generic;
using System.Linq;
using DesignPatterns.BuilderPattern.Models;

namespace DesignPatterns.BuilderPattern.Repositories
{
    /// <summary>
    /// Notice how this interface doesn't contain the methods to get/save address for a person.
    /// This only contains the method to get addresses. 
    /// </summary>
    public interface IAddressRepository 
    {
        List<Address> GetAll();
        Address GetById(int id);
    }

    /// <summary>
    /// The single responsibility for this class is to get and save address to the database
    /// </summary>
    public class AddressRepository : IPersonBuilder, IAddressRepository
    {
        public List<Address> GetAll()
        {
            return new List<Address>
            {
                new Address { Id = 1, Number = 123, Street = "Main St.", City = "Louisville", State = "KY", ZipCode = 40229},
                new Address { Id = 2, Number = 123, Street = "1st St.", City = "Boston", State = "MA", ZipCode = 12345},
                new Address { Id = 3, Number = 123, Street = "8th St.", City = "York", State = "PA", ZipCode = 23456},
                new Address { Id = 4, Number = 123, Street = "Broadway", City = "New York", State = "NY", ZipCode = 56789},
                new Address { Id = 5, Number = 123, Street = "Abby Ln.", City = "Nashville", State = "TN", ZipCode = 78965},
                new Address { Id = 6, Number = 123, Street = "Lumbard St.", City = "San Francisco", State = "CA", ZipCode = 45123}
            };
        }

        public Address GetById(int id)
        {
            return GetAll().FirstOrDefault(i => i.Id == id);
        }

        public List<Address> GetByPerson(int personId)
        {
            /****** THIS METHOD WOULD BE EASY TO UNIT/INTEGRATION TEST ******/

            //Query the database to get address for this person id
            //this would probably be a many to many table
            return GetAll().Where(i => new[] {1, 3, 6}.Contains(i.Id)).ToList();
        }

        public void SaveAddressForPerson(int personId, List<Address> addresses)
        {
            /****** THIS METHOD WOULD BE EASY TO UNIT/INTEGRATION TEST ******/

            //Save the many to many relations to the database
        }


        public void Populate(ref Person item)
        {
            if (item == null) return;

            item.Addresses = GetByPerson(item.Id);
        }

        public void Save(ref Person item)
        {
            if (item == null) return;
            
            SaveAddressForPerson(item.Id, item.Addresses);
        }
    }
}
